package com.example.venue_reservation_service.exception;

import com.example.venue_reservation_service.domain.VeException;
import com.example.venue_reservation_service.service.VeExceptionService;
import com.example.venue_reservation_service.vo.Result;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerMapping;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.time.LocalDateTime;
import java.util.Map;

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @Autowired
    private VeExceptionService exceptionService;

    // 文件移除异常处理
    @ExceptionHandler(MinioRemoveException.class)
    public Result handleMinioRemoveException(MinioRemoveException e) {
        log.error("文件移除失败: {}", e.getMessage());
        recordException(e, "MinioRemoveException");
        return Result.fail().message("旧头像删除失败，请重试");
    }

    // 文件校验异常处理
    @ExceptionHandler(ImageValidateException.class)
    public Result handleImageValidateException(ImageValidateException e) {
        String errorMsg = "FILE_SIZE".equals(e.getErrorType())
                ? "文件大小超过250MB限制" : "不支持的文件类型";
        log.error("文件校验失败: {} - {}", e.getErrorType(), e.getMessage());
        recordException(e, "ImageValidateException");
        return Result.fail().message(errorMsg);
    }

    // 文件上传异常处理
    @ExceptionHandler(MinioUploadException.class)
    public Result handleMinioUploadException(MinioUploadException e) {
        log.error("文件上传失败: {}", e.getMessage());
        recordException(e, "MinioUploadException");
        return Result.fail().message("头像上传失败，请稍后重试");
    }

    // 新增敏感词过滤异常处理
    @ExceptionHandler(SensitiveFilterException.class)
    public Result handleSensitiveFilterException(SensitiveFilterException e) {
        log.error("敏感词处理异常 [错误码:{}]: {}", e.getErrorCode(), e.getMessage(), e);
        recordException(e, "SensitiveFilterException");

        // 根据错误码返回不同提示
        if ("SENSITIVE_001".equals(e.getErrorCode())) {
            return Result.fail().message("评论服务暂时不可用，请稍后再试");
        } else {
            return Result.fail().message("评论处理失败，请重试");
        }
    }

    // 新增敏感词操作异常处理
    @ExceptionHandler(SensitiveWordException.class)
    public Result handleSensitiveWordException(SensitiveWordException e) {
        log.error("敏感词操作异常 [错误码:{}]: {}", e.getErrorCode(), e.getMessage(), e);
        recordException(e, "SensitiveWordException");

        // 根据错误码返回不同提示
        if ("SENSITIVE_002".equals(e.getErrorCode())) {
            return Result.fail().message("敏感词状态更新失败，请稍后重试");
        } else {
            return Result.fail().message("敏感词操作失败，请重试");
        }
    }

    // 身份认证API调用异常处理
    @ExceptionHandler(IdentityApiException.class)
    public Result handleIdentityApiException(IdentityApiException e) {
        log.error("身份认证接口调用失败: {}", e.getMessage(), e);
        recordException(e, "IdentityApiException");
        return Result.fail().message("身份认证服务暂时不可用，请稍后再试");
    }

    // 记录异常到数据库
    private void recordException(Exception e, String exceptionType) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes)
                    RequestContextHolder.currentRequestAttributes()).getRequest();

            HandlerMethod handlerMethod = (HandlerMethod) request.getAttribute(
                    HandlerMapping.BEST_MATCHING_HANDLER_ATTRIBUTE);

            VeException logEntity = new VeException();
            logEntity.setExceptionType(exceptionType);
            logEntity.setExceptionMessage(e.getMessage());

            // 获取堆栈信息
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            logEntity.setExceptionStack(sw.toString());

            logEntity.setMethodName(handlerMethod.getMethod().getName());

            // 获取参数数据
            Map<String, String[]> params = request.getParameterMap();
            logEntity.setParameterData(params.toString());

            // 从请求中获取用户ID
            String userId = request.getParameter("userId");
            if (userId != null) {
                logEntity.setUserId(Integer.parseInt(userId));
            }

            logEntity.setOperationTime(LocalDateTime.now());

            exceptionService.save(logEntity);
        } catch (Exception ex) {
            log.error("记录异常日志失败: {}", ex.getMessage());
        }
    }
}